//+FHDR-------------------------------------------------------------------------
//            __     __ __                  ____     ___ ___
//           |  |   |  /__| ____ ___ ___   /    \   /  ____/
//           |  \___/  |  /   __    __   \/  __  \ /  /
//           |   ___   |  |  /  \  /  \     /__\  (  <
//           |  /   \  |  |  |  |  |  |    /    \     \____
//           |__|   |__ __ __|  |__|  |___/      \__ __ ___\ 2.0                     
//------------------------------------------------------------------------------
//-- Module Name     :    fp_rx_ctrl
//-- Hierarchy       :    frame_process - * - fp_rx_ctrl
//-- Description     :    分组处理模块中接收部分的顶层                                             
//                                                                              
//-- Last Modified   : 2013-02-26 15:09
//-- Revision history:                                                          
//     Date               Author       Description                              
//     2012-12-20 15:01   Tiger        2012.12对分组处理的改动
//-FHDR-------------------------------------------------------------------------

`timescale 1ns/100ps
`include "top_define.v"
/***************************************************************/
//将数据存入FIFO中
//FIFO的宽度为256+1+1+5=263bit，深度为256=128个最短帧=5个最长帧
/***************************************************************/

module fp_rx_ctrl(
                  input clk,
                  input rst_n,
                  input [9:0]ram_2p_cfg_register,
		  input [6:0] rf_2p_cfg_register ,
                  input mem_que_rdy,

                  //数据输入接口
                  output rx_rdy,
                  output rd_rdy,
                  input rx_ff_sop,
                  input rx_ff_eop,
                  input rx_ff_dval,
                  //input rx_ff_dsav,
                  input [255:0] rx_ff_data,
                  input [4:0] rx_ff_mod,
                  //input rx_ff_err,
                  input [7:0] src_node_id_i,                
                  input insert_frame_flag, 
                  input [7:0] insert_des_node_id,
                  input [2:0] pri_insert_i,
                  
                  //读数据帧接口
                  output [262:0] fp_dpram_data,          
                  input  fp_dpram_rden,               
                  //帧长FIFO接口
                  input    fifo_full,
                  output   fifo_wren,
                  output [10:0] frame_length,
                  //将插入帧的信息存储起来提供给action_exe模块
                  output wire des_node_wen,
                  output wire[7:0] des_node_id,
                  output wire[2:0] pri_insert_o,
                  //需要直接捕获的帧类型
                  input  wire [15:0] eth_type,
                  output wire direct_capture,
                  //add by Hbing 8-10
                  output wire in_buf_val,   //调度信息有效信号
                  output wire multicast,  //组播帧
                  input  wire schedule_start,  //调度模块的应答信号，表示以上帧信息已经被接收，维持一周期高电平

                  output wire [ 7:0] src_node_id,
                  output wire [47:0] mac_des_addr,
                  output wire [47:0] mac_src_addr,  //MAC地址用来查找单播表
                  output wire [128:0] ip_src_addr,
                  output wire [128:0] ip_des_addr,  //是否需要支持IGMP V3源地址过滤？ 

                  input  access_fail,
                  output wire in_buf_access_fail
                 );


//让eop提前一拍--对应修改，fifo的prog——full应提前两拍产生
reg         rx_ff_sop_dl;
reg         rx_ff_sop_dl2;
reg         rx_ff_eop_dl;
reg [4:0]   rx_ff_mod_dl;
reg [4:0]   rx_ff_mod_dl2;
reg [255:0] rx_ff_data_dl;
reg [255:0] rx_ff_data_dl2;
reg         rx_ff_dval_dl;
reg         rx_ff_dval_dl2;

wire empty,full;
/***************************************************************/
//                控制信息的处理模块
/***************************************************************/
fp_info_ctrl U_info_ctrl(
                       .clk(clk),
                       .rst_n(rst_n),
                       .mem_que_rdy(mem_que_rdy),
                       //帧长信息接口
                       .fifo_full(fifo_full),                                     
                       .fifo_wren(fifo_wren),
                       .frame_length(frame_length),

                       //数据帧信息
                       .rx_ff_sop(rx_ff_sop),
                       .rx_ff_eop(rx_ff_eop),
                       .rx_ff_mod(rx_ff_mod),
                       .rx_ff_dval(rx_ff_dval),
                       .insert_frame_flag(insert_frame_flag),
                       .insert_des_node_id(insert_des_node_id),
                       .pri_insert_i(pri_insert_i),

                       //插入帧的处理
                       .des_node_wen(des_node_wen),
                       .des_node_id(des_node_id),
                       .pri_insert_o(pri_insert_o),

                       //模块状态信号
                       .empty(empty),
                       .full(full),
                       .rx_rdy(rx_rdy),           //有空间来接收帧
                       .rd_rdy(rd_rdy)            //fifo中有可以读的数据
                      );

/***************************************************************/
//           将所有的RAM对外封装成一个RAM接口
/***************************************************************/
//可存128个最短帧=5个最长帧
/*  fp_frame_fifo #(
      .PTR(8),
      .WORDS(256),
      .W_SIZE(263),
      .A_FULL(208)  //256-48(一个最长帧)
    ) inst_fp_frame_fifo (
      .clock         (clk),
      .rst_n         (rst_n),
      .fifo_wen      (rx_ff_dval),
      .fifo_wdata    ({rx_ff_sop,rx_ff_eop,rx_ff_mod,rx_ff_data}),
      .fifo_ren      (fp_dpram_rden),
      .fifo_rdata    (fp_dpram_data),
      .fifo_empty_rd (empty),
      .almost_full   (full)
    );*/
`ifdef ASIC
fp_frame_fifo_fwft inst_fp_frame_fifo_asic(
  .clk(clk),
  .clr(rst_n),
  .ram_2p_cfg_register(ram_2p_cfg_register),
                            
  .w_data({rx_ff_sop_dl2,rx_ff_eop_dl,rx_ff_mod_dl2,rx_ff_data_dl2}),
  .w_we(rx_ff_dval_dl2),
  .w_full(),
  .w_afull(full),
                           
  .r_data(fp_dpram_data),
  .r_re(fp_dpram_rden),
  .r_empty(empty),
  .r_aempty()
);
`else
fp_frame_fifo_ip inst_fp_frame_fifo (
  .clk(clk),              // input wire clk
  .rst(~rst_n),              // input wire rst
  .din({rx_ff_sop_dl2,rx_ff_eop_dl,rx_ff_mod_dl2,rx_ff_data_dl2}),              // input wire [262 : 0] din
  .wr_en(rx_ff_dval_dl2),          // input wire wr_en
  .rd_en(fp_dpram_rden),          // input wire rd_en
  .dout(fp_dpram_data),            // output wire [262 : 0] dout
  .full( ),            // output wire full
  .empty(empty),          // output wire empty
  .prog_full(full)  // output wire prog_full
);
`endif

  fp_frame_info_collect inst_fp_frame_info_collect
    (
      .clk            (clk),
      .rst_n          (rst_n),
      .rf_2p_cfg_register(rf_2p_cfg_register),
      .rx_ff_sop      (rx_ff_sop),
      .rx_ff_eop      (rx_ff_eop),
      .rx_ff_dval     (rx_ff_dval),
      .rx_ff_data     (rx_ff_data),
      //.rx_ff_mod      (rx_ff_mod),
      .src_node_id_i  (src_node_id_i),
      .eth_type       (eth_type),
      .direct_capture (direct_capture),
      .schedule_start (schedule_start),
      .in_buf_val     (in_buf_val),
      .src_node_id    (src_node_id),
      .mac_src_addr   (mac_src_addr),
      .mac_des_addr   (mac_des_addr),
      .ip_des_addr    (ip_des_addr),
      .ip_src_addr    (ip_src_addr),
      .multicast      (multicast),
      .access_fail    (access_fail),
      .in_buf_access_fail(in_buf_access_fail) 
    );

//*********************
//MAIN CORE
//*********************
always @(posedge clk or negedge rst_n) begin
    if(~rst_n) begin
      rx_ff_sop_dl    <=   1'b0;
      rx_ff_sop_dl2   <=   1'b0;
      rx_ff_eop_dl    <=   1'b0;
      rx_ff_mod_dl    <=   5'b0;
      rx_ff_mod_dl2   <=   5'b0;
      rx_ff_data_dl   <= 256'b0;
      rx_ff_data_dl2  <= 256'b0;
      rx_ff_dval_dl   <=   1'b0;
      rx_ff_dval_dl2  <=   1'b0;
    end
    else begin
      rx_ff_sop_dl    <= rx_ff_sop    ;
      rx_ff_sop_dl2   <= rx_ff_sop_dl ;
      rx_ff_eop_dl    <= rx_ff_eop    ;
      rx_ff_mod_dl    <= rx_ff_mod    ;
      rx_ff_mod_dl2   <= rx_ff_mod_dl ;
      rx_ff_data_dl   <= rx_ff_data   ;
      rx_ff_data_dl2  <= rx_ff_data_dl;
      rx_ff_dval_dl   <= rx_ff_dval   ;
      rx_ff_dval_dl2  <= rx_ff_dval_dl;
    end
end

//mark_debug
(*mark_debug = "true"*) reg [31:0] fp_frame_in_cnt;

always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        fp_frame_in_cnt <= 32'd0;
    end
    else if (rx_ff_sop && rx_ff_eop) begin
        fp_frame_in_cnt <= fp_frame_in_cnt + 32'b1;
    end
    else begin
        fp_frame_in_cnt <= fp_frame_in_cnt;
    end
end


endmodule
